package com.googlecode.olabs.common.server.contact.formats.json;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.googlecode.olabs.common.client.contact.Contact;
import com.googlecode.olabs.common.client.contact.ContactException;
import com.googlecode.olabs.common.client.contact.ContactImpl;
import com.googlecode.olabs.common.client.contact.field.IdField;
import com.googlecode.olabs.common.client.contact.formats.AbstractParser;
import com.googlecode.olabs.common.client.contact.formats.json.JsonFormat;

public class JsonDesktopParser extends AbstractParser {

	public Contact parse(List<String> rawText) throws ContactException {
		Contact contact = new ContactImpl();
		for (String line : rawText) {
			try {
				JSONObject object = new JSONObject(line);
				verifyKeyValuePair(object, JsonFormat.KEY_FORMAT,
						JsonFormat.VALUE_FORMAT);
				verifyKeyValuePair(object, JsonFormat.KEY_VERSION,
						JsonFormat.VALUE_VERSION);
				String id = object.getString(JsonFormat.KEY_ID);
				if (id == null) {
					throw new ContactException("Missing a value for "
							+ JsonFormat.KEY_ID);
				}
				IdField idField = new IdField();
				idField.setValue(Arrays.asList(new String[] { id }));
				contact.getFields().add(idField);
				JSONArray fields = object.getJSONArray(JsonFormat.KEY_FIELDS);

				for (int i = 0; i < fields.length(); i++) {
					JSONObject field = fields.getJSONObject(i);
					String type = field.getString(JsonFormat.KEY_FIELD_TYPE);
					JSONArray subTypes = field
							.getJSONArray(JsonFormat.KEY_FIELD_SUBTYPE);
					JSONArray values = field
							.getJSONArray(JsonFormat.KEY_FIELD_VALUE);
					super.createField(type, convertToList(subTypes),
							convertToList(values));
				}
			} catch (JSONException e) {
				throw new ContactException(e.getMessage());
			}
		}
		return contact;
	}

	private List<String> convertToList(JSONArray array) throws JSONException {
		List<String> result = new ArrayList<String>(array.length());
		for (int i = 0; i < array.length(); i++) {
			result.add(array.getString(i));
		}
		return result;
	}

	private void verifyKeyValuePair(JSONObject object, String key, String value)
			throws ContactException {
		try {
			String innerValue = object.getString(key);
			if (innerValue == null || innerValue.equals(value)) {
				throw new ContactException("Missing " + key + ":" + value);
			}
		} catch (JSONException e) {
			throw new ContactException(e.getMessage());
		}
	}

}
